/******************************************************************************* * Copyright (c) 2004, 2013 Richard Hoefter and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Richard Hoefter (richard.hoefter@web.de) - initial API and implementation, bug 95296, bug 288830 * IBM Corporation - adapted to wizard export page *******************************************************************************/ package org.eclipse.ant.internal.ui.datatransfer; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.TreeSet; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import org.eclipse.ant.internal.ui.AntUIPlugin; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.jdt.core.IJavaModel; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.TableLayout; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.model.WorkbenchContentProvider; import org.eclipse.ui.model.WorkbenchLabelProvider; import com.ibm.icu.text.MessageFormat; public class AntBuildfileExportPage extends WizardPage { private CheckboxTableViewer fTableViewer; private List<IJavaProject> fSelectedJavaProjects = new ArrayList<>(); private Button compatibilityCheckbox; private Button compilerCheckbox; private Text buildfilenameText; private Text junitdirText; public AntBuildfileExportPage() { super("AntBuildfileExportWizardPage"); //$NON-NLS-1$ setPageComplete(false); setTitle(DataTransferMessages.AntBuildfileExportPage_0); setDescription(DataTransferMessages.AntBuildfileExportPage_1); } /* * @see IDialogPage#createControl(Composite) */ @Override public void createControl(Composite parent) { initializeDialogUnits(parent); Composite workArea = new Composite(parent, SWT.NONE); setControl(workArea); workArea.setLayout(new GridLayout()); workArea.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL)); Label titel = new Label(workArea, SWT.NONE); titel.setText(DataTransferMessages.AntBuildfileExportPage_2); Composite listComposite = new Composite(workArea, SWT.NONE); GridLayout layout = new GridLayout(); layout.numColumns = 2; layout.marginWidth = 0; layout.makeColumnsEqualWidth = false; listComposite.setLayout(layout); listComposite.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_BOTH)); // TODO set F1 help Table table = new Table(listComposite, SWT.CHECK | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); fTableViewer = new CheckboxTableViewer(table); table.setLayout(new TableLayout()); GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); data.heightHint = 300; table.setLayoutData(data); fTableViewer.setContentProvider(new WorkbenchContentProvider() { @Override public Object[] getElements(Object element) { if (element instanceof IJavaProject[]) { return (IJavaProject[]) element; } return null; } }); fTableViewer.setLabelProvider(new WorkbenchLabelProvider()); fTableViewer.addCheckStateListener(new ICheckStateListener() { @Override public void checkStateChanged(CheckStateChangedEvent event) { if (event.getChecked()) { fSelectedJavaProjects.add((IJavaProject) event.getElement()); } else { fSelectedJavaProjects.remove(event.getElement()); } updateEnablement(); } }); initializeProjects(); createSelectionButtons(listComposite); createCheckboxes(workArea); createTextFields(workArea); setControl(workArea); updateEnablement(); Dialog.applyDialogFont(parent); } private void createSelectionButtons(Composite composite) { Composite buttonsComposite = new Composite(composite, SWT.NONE); GridLayout layout = new GridLayout(); layout.marginWidth = 0; layout.marginHeight = 0; buttonsComposite.setLayout(layout); buttonsComposite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)); Button selectAll = new Button(buttonsComposite, SWT.PUSH); selectAll.setText(DataTransferMessages.AntBuildfileExportPage_11); selectAll.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { for (int i = 0; i < fTableViewer.getTable().getItemCount(); i++) { fSelectedJavaProjects.add((IJavaProject) fTableViewer.getElementAt(i)); } fTableViewer.setAllChecked(true); updateEnablement(); } }); setButtonLayoutData(selectAll); Button deselectAll = new Button(buttonsComposite, SWT.PUSH); deselectAll.setText(DataTransferMessages.AntBuildfileExportPage_12); deselectAll.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { fSelectedJavaProjects.clear(); fTableViewer.setAllChecked(false); updateEnablement(); } }); setButtonLayoutData(deselectAll); } private void createCheckboxes(Composite composite) { compatibilityCheckbox = new Button(composite, SWT.CHECK); compatibilityCheckbox.setSelection(true); compatibilityCheckbox.setText(DataTransferMessages.AntBuildfileExportPage_13); compatibilityCheckbox.setToolTipText(DataTransferMessages.AntBuildfileExportPage_14); compilerCheckbox = new Button(composite, SWT.CHECK); compilerCheckbox.setSelection(true); compilerCheckbox.setText(DataTransferMessages.AntBuildfileExportPage_15); } private void createTextFields(Composite composite) { // buildfilename and junitdir group Composite containerGroup = new Composite(composite, SWT.NONE); GridLayout layout = new GridLayout(); layout.numColumns = 2; containerGroup.setLayout(layout); containerGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); // label Label buildfilenameLabel = new Label(containerGroup, SWT.NONE); buildfilenameLabel.setText(DataTransferMessages.AntBuildfileExportPage_16); // text field buildfilenameText = new Text(containerGroup, SWT.SINGLE | SWT.BORDER); buildfilenameText.setText("build.xml"); //$NON-NLS-1$ GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL); buildfilenameText.setLayoutData(data); // label Label junitdirLabel = new Label(containerGroup, SWT.NONE); junitdirLabel.setText(DataTransferMessages.AntBuildfileExportPage_17); // text field junitdirText = new Text(containerGroup, SWT.SINGLE | SWT.BORDER); junitdirText.setText("junit"); //$NON-NLS-1$ junitdirText.setLayoutData(data); ModifyListener listener = new ModifyListener() { @Override public void modifyText(ModifyEvent e) { updateEnablement(); } }; buildfilenameText.addModifyListener(listener); junitdirText.addModifyListener(listener); } private void initializeProjects() { IWorkspaceRoot rootWorkspace = ResourcesPlugin.getWorkspace().getRoot(); IJavaModel javaModel = JavaCore.create(rootWorkspace); IJavaProject[] javaProjects; try { javaProjects = javaModel.getJavaProjects(); } catch (JavaModelException e) { javaProjects = new IJavaProject[0]; } fTableViewer.setInput(javaProjects); // Check any necessary projects if (fSelectedJavaProjects != null) { fTableViewer.setCheckedElements(fSelectedJavaProjects.toArray(new IJavaProject[fSelectedJavaProjects.size()])); } } private void updateEnablement() { boolean complete = true; if (fSelectedJavaProjects.size() == 0) { setErrorMessage(DataTransferMessages.AntBuildfileExportPage_18); complete = false; } try { List<String> projectsWithErrors = new ArrayList<>(); List<String> projectsWithWarnings = new ArrayList<>(); findCyclicProjects(getProjects(false), projectsWithErrors, projectsWithWarnings); if (projectsWithErrors.size() > 0) { String message = DataTransferMessages.AntBuildfileExportPage_cycle_error_in_projects; if (projectsWithErrors.size() == 1) { message = DataTransferMessages.AntBuildfileExportPage_cycle_error_in_project; } setErrorMessage(MessageFormat.format(message, new Object[] { ExportUtil.toString(projectsWithErrors, ", ") })); //$NON-NLS-1$ complete = false; } else if (projectsWithWarnings.size() > 0) { String message = DataTransferMessages.AntBuildfileExportPage_cycle_warning_in_projects; if (projectsWithWarnings.size() == 1) { message = DataTransferMessages.AntBuildfileExportPage_cycle_warning_in_project; } setMessage(MessageFormat.format(message, new Object[] { ExportUtil.toString(projectsWithWarnings, ", ") }), WARNING); //$NON-NLS-1$ } else { setMessage(null); } } catch (CoreException e) { // do nothing } if (buildfilenameText.getText().length() == 0) { setErrorMessage(DataTransferMessages.AntBuildfileExportPage_19); complete = false; } if (junitdirText.getText().length() == 0) { setErrorMessage(DataTransferMessages.AntBuildfileExportPage_20); complete = false; } if (complete) { setErrorMessage(null); } setPageComplete(complete); } /* * (non-Javadoc) * * @see org.eclipse.jface.dialogs.IDialogPage#setVisible(boolean) */ @Override public void setVisible(boolean visible) { super.setVisible(visible); if (visible) { fTableViewer.getTable().setFocus(); } } protected void setSelectedProjects(List<IJavaProject> selectedJavaProjects) { fSelectedJavaProjects.addAll(selectedJavaProjects); } /** * Convert Eclipse Java projects to Ant build files. Displays error dialogs. */ public boolean generateBuildfiles() { setErrorMessage(null); final List<String> projectNames = new ArrayList<>(); final Set<IJavaProject> projects; try { projects = getProjects(true); if (projects.size() == 0) { return false; } } catch (JavaModelException e) { AntUIPlugin.log(e); setErrorMessage(MessageFormat.format(DataTransferMessages.AntBuildfileExportPage_10, new Object[] { e.toString() })); return false; } IRunnableWithProgress runnable = new IRunnableWithProgress() { @Override public void run(IProgressMonitor pm) throws InterruptedException { SubMonitor localmonitor = SubMonitor.convert(pm, DataTransferMessages.AntBuildfileExportPage_creating_build_files, projects.size()); Exception problem = null; try { BuildFileCreator.setOptions(buildfilenameText.getText(), junitdirText.getText(), compatibilityCheckbox.getSelection(), compilerCheckbox.getSelection()); projectNames.addAll(BuildFileCreator.createBuildFiles(projects, getShell(), localmonitor.newChild(projects.size()))); } catch (JavaModelException e) { problem = e; } catch (TransformerConfigurationException e) { problem = e; } catch (ParserConfigurationException e) { problem = e; } catch (TransformerException e) { problem = e; } catch (IOException e) { problem = e; } catch (CoreException e) { problem = e; } if (problem != null) { AntUIPlugin.log(problem); setErrorMessage(MessageFormat.format(DataTransferMessages.AntBuildfileExportPage_10, new Object[] { problem.toString() })); } } }; try { getContainer().run(false, false, runnable); } catch (InvocationTargetException e) { AntUIPlugin.log(e); return false; } catch (InterruptedException e) { AntUIPlugin.log(e); return false; } if (getErrorMessage() != null) { return false; } return true; } /** * Get projects to write buildfiles for. Opens confirmation dialog. * * @param displayConfirmation * if set to true a dialog prompts for confirmation before overwriting files * @return set of project names */ private Set<IJavaProject> getProjects(boolean displayConfirmation) throws JavaModelException { // collect all projects to create buildfiles for Set<IJavaProject> projects = new TreeSet<>(ExportUtil.getJavaProjectComparator()); Iterator<IJavaProject> javaProjects = fSelectedJavaProjects.iterator(); while (javaProjects.hasNext()) { IJavaProject javaProject = javaProjects.next(); projects.addAll(ExportUtil.getClasspathProjectsRecursive(javaProject)); projects.add(javaProject); } // confirm overwrite List<String> confirmOverwrite = getConfirmOverwriteSet(projects); if (displayConfirmation && confirmOverwrite.size() > 0) { String message = DataTransferMessages.AntBuildfileExportPage_3 + ExportUtil.NEWLINE + ExportUtil.toString(confirmOverwrite, ExportUtil.NEWLINE); if (!MessageDialog.openQuestion(getShell(), DataTransferMessages.AntBuildfileExportPage_4, message)) { return new TreeSet<>(ExportUtil.getJavaProjectComparator()); } } return projects; } /** * Splits a set of given projects into a list of projects that have cyclic dependency errors and a list of projects that have cyclic dependency * warnings. */ private void findCyclicProjects(Set<IJavaProject> projects, List<String> errors, List<String> warnings) throws CoreException { for (Iterator<IJavaProject> iter = projects.iterator(); iter.hasNext();) { IJavaProject javaProject = iter.next(); IMarker marker = ExportUtil.getCyclicDependencyMarker(javaProject); if (marker != null) { Integer severityAttr = (Integer) marker.getAttribute(IMarker.SEVERITY); if (severityAttr != null) { switch (severityAttr.intValue()) { case IMarker.SEVERITY_ERROR: errors.add(javaProject.getProject().getName()); break; case IMarker.SEVERITY_WARNING: warnings.add(javaProject.getProject().getName()); break; default: break; } } } } } /** * Get list of projects which have already a buildfile that was not created by the buildfile export. * * @param javaProjects * list of IJavaProject objects * @return set of project names */ private List<String> getConfirmOverwriteSet(Set<IJavaProject> javaProjects) { List<String> result = new ArrayList<>(javaProjects.size()); for (IJavaProject project : javaProjects) { String projectRoot = ExportUtil.getProjectRoot(project); if (ExportUtil.existsUserFile(projectRoot + buildfilenameText.getText())) { result.add(project.getProject().getName()); } } return result; } }